tooling: Add firmware build and deploy targets.#246
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a local firmware workflow to this repository so developers can build MicroPython firmware with the repo’s drivers frozen in, flash it via OpenOCD, and push a main.py to the board for quick iteration.
Changes:
- Introduces Makefile targets for firmware clone/build, deploy (OpenOCD), run (copy script + reset), and firmware-clean.
- Adds firmware-related configuration variables to
env.mk(repo/branch/board/build dirs). - Documents the workflow in
CONTRIBUTING.mdand gitignores the local build directory.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
env.mk |
Adds firmware build configuration variables (repo/branch/board/build paths). |
Makefile |
Adds firmware, deploy, run, firmware-clean targets and extends deepclean to remove firmware build dir. |
CONTRIBUTING.md |
Documents the new firmware build/deploy/run workflow and requirements. |
.gitignore |
Ignores .build/ where firmware sources/artifacts are cloned/built. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| # --- Firmware --- | ||
|
|
||
| $(MPY_DIR): |
There was a problem hiding this comment.
git clone ... $(MPY_DIR) will fail on a fresh checkout if $(BUILD_DIR) (default .build) doesn’t exist, because git clone won’t create missing parent directories. Create $(BUILD_DIR) first (e.g., mkdir -p $(BUILD_DIR)) before cloning, or set MPY_DIR to a path whose parents are guaranteed to exist.
| $(MPY_DIR): | |
| $(MPY_DIR): | |
| @mkdir -p $(dir $(MPY_DIR)) |
There was a problem hiding this comment.
Fixed in 95028ee. Added mkdir -p before clone.
| @echo "Updating submodule to current HEAD..." | ||
| cd $(MPY_DIR)/lib/micropython-steami-lib && \ | ||
| git fetch origin && \ | ||
| git checkout $$(cd $(CURDIR) && git rev-parse HEAD) |
There was a problem hiding this comment.
The “update submodule to current HEAD” logic is unlikely to work for local/unpushed commits: the submodule fetches only from its own origin, then tries to checkout a SHA from the parent repo. If that SHA isn’t present in the submodule clone, this will fail and it also won’t include uncommitted local changes. Consider fetching from the local working tree path (or setting the submodule URL to the local repo) and clarify whether users must commit changes before building firmware.
| @echo "Updating submodule to current HEAD..." | |
| cd $(MPY_DIR)/lib/micropython-steami-lib && \ | |
| git fetch origin && \ | |
| git checkout $$(cd $(CURDIR) && git rev-parse HEAD) | |
| @echo "Updating submodule to current committed HEAD from local repo (uncommitted changes are not included)..." | |
| cd $(MPY_DIR)/lib/micropython-steami-lib && \ | |
| git fetch "$(CURDIR)" HEAD && \ | |
| git checkout FETCH_HEAD |
There was a problem hiding this comment.
Fixed in 95028ee. Replaced git fetch origin with a symlink: rm -rf ... && ln -s $(CURDIR) .... This way the firmware includes all local changes — even uncommitted ones — without needing to fetch or push.
| @echo "Firmware ready: $(MPY_DIR)/ports/stm32/build-$(BOARD)/firmware.hex" | ||
|
|
||
| .PHONY: deploy | ||
| deploy: ## Flash firmware to the board via OpenOCD |
There was a problem hiding this comment.
deploy assumes $(MPY_DIR) already exists; running make deploy in a clean repo will fail because the clone hasn’t happened yet. Make deploy depend on $(MPY_DIR) (and likely firmware if you expect a freshly built hex) so it works from a fresh checkout.
| deploy: ## Flash firmware to the board via OpenOCD | |
| deploy: firmware ## Flash firmware to the board via OpenOCD |
There was a problem hiding this comment.
Fixed in 95028ee. deploy now depends on $(MPY_DIR) — ensures the clone exists but doesn't force a rebuild. Use make firmware deploy for a full build+flash.
| .PHONY: run | ||
| run: ## Copy and run a script on the board (SCRIPT=path/to/file.py) | ||
| @if [ -z "$(SCRIPT)" ]; then \ | ||
| echo "Error: SCRIPT is required. Usage: make run SCRIPT=lib/.../example.py"; exit 1; \ | ||
| fi | ||
| mpremote connect $(PORT) cp $(SCRIPT) :main.py | ||
| mpremote connect $(PORT) reset | ||
| @echo "Script deployed as main.py and board reset." |
There was a problem hiding this comment.
There was a problem hiding this comment.
| deepclean: clean ## Remove everything including node_modules | ||
| deepclean: clean ## Remove everything including node_modules and firmware | ||
| rm -rf node_modules | ||
| @if [ -d "$(BUILD_DIR)" ]; then rm -rf $(BUILD_DIR); fi |
There was a problem hiding this comment.
In .ONESHELL mode, prefer quoting $(BUILD_DIR) in rm -rf (and you can usually drop the -d guard since rm -rf is already idempotent). Unquoted paths can behave unexpectedly if the variable is overridden with spaces or glob characters.
| @if [ -d "$(BUILD_DIR)" ]; then rm -rf $(BUILD_DIR); fi | |
| rm -rf "$(BUILD_DIR)" |
There was a problem hiding this comment.
Fixed in 95028ee. Quoted $(BUILD_DIR) in rm -rf.
| The firmware source is cloned into `.build/micropython-steami/` (gitignored). The submodule `lib/micropython-steami-lib` is pointed to the current HEAD of your local branch, so the firmware always includes your latest driver changes. | ||
|
|
||
| **Requirements**: `arm-none-eabi-gcc` toolchain and OpenOCD for flashing. |
There was a problem hiding this comment.
The docs say the firmware submodule is pointed to “the current HEAD of your local branch” and list requirements only as GCC + OpenOCD, but the Makefile currently fetches from the submodule’s origin (so local/unpushed commits won’t be available) and make run requires mpremote to be installed. Please align this section with the actual behavior and list mpremote as a requirement for deploy/run.
There was a problem hiding this comment.
Fixed in 95028ee. Updated CONTRIBUTING.md: added mpremote to requirements, clarified symlink behavior (local working directory, includes uncommitted changes), and documented all new targets (run, deploy-script, run-main).
|
🎉 This PR is included in version 0.1.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
Add Makefile targets for building, deploying, and running MicroPython firmware with current drivers.
Closes #245
New targets
make firmwaremake deploymake run SCRIPT=...mpremote runmake deploy-script SCRIPT=...main.pyfor autonomous executionmake run-mainmain.pyand capture outputmake firmware-cleanArchitecture
The firmware source is cloned into
.build/micropython-steami/(gitignored). A symbolic link replaces the submodulelib/micropython-steami-libwith the local working directory. This means the firmware always includes the latest driver changes — even uncommitted ones — without needing to commit or push first.Configuration
Variables in
env.mk(all overridable):Typical workflow
Requirements
arm-none-eabi-gcctoolchainmpremotefor running scriptsReview feedback addressed
mkdir -pbefore clone to handle missing parent directoriesdeploydepends on$(MPY_DIR)(clone must exist, but no forced rebuild)runvsdeploy-scriptvsrun-mainroles$(BUILD_DIR)inrm -rffor safetympremoterequirement and symlink docs